<?php

require_once realpath (dirname (__FILE__) . '//..//pages.php');
require_once INC_FUNCTIONS;

/**
 * Description of Database
 *
 * @author Andrea Cantafio
 */
class Database {

    private $server, $user, $pass, $database;
    private $link;
    private $allow_empty_values = true, $debug_mode = true, $escape;

    public function __construct ($server, $user, $pass, $database = null) {
        $this->escape = !get_magic_quotes_gpc ();
        $this->escape (func_get_args ());
        $this->link = mysql_connect ($server, $user, $pass);
        if ($this->link) {
            $this->server = $server;
            $this->user = $user;
            $this->pass = $pass;
        } else {
            return false;
        }
        if (isset ($database) && !empty ($database)) {
            if (mysql_select_db ($database)) {
                $this->database = $database;
            } else {
                return false;
            }
        }
    }

    public function __destruct () {
        foreach ($this as $key => $value) {
            unset ($this->$key);
        }
    }

    public function affectedRows () {
        return mysql_affected_rows ($this->link);
    }

    /**
     * This method is used to close current session
     *
     * @return bool true on success or false on failure.
     */
    public function close () {
        mysql_close ($this->link);
        $this->link = null;
    }

    public function count ($table, $field = null, $where = null) {
        if (!isset ($field)) {
            $field = '*';
        }
        $row = $this->fetchAssoc ($this->select ($table, "COUNT(*) AS n", $where));
        return $row['n'];
    }

    public function delete ($table, $where = null) {
        $this->escape (func_get_args ());
        $query = "DELETE FROM $table";
        if (isset ($where)) {
            if (isset ($where) && !empty ($where)) {
                $query .= " WHERE $where";
            }
        }
        return $this->query ($query);
    }

    public function errno () {
        return mysql_errno ();
    }

    public function error () {
        return mysql_error ($this->link);
    }

    public function fetchAssoc ($result) {
        return mysql_fetch_assoc ($result);
    }

    function backup ($file) {
        $this->escape (func_get_args ());
        $tables = $this->getTables ();
        foreach ($tables as $table) {
            if (!$this->query ("SELECT * INTO OUTFILE $table.backup FROM $table")) {
                return false;
            }
        }
        return true;
    }

    public function getFields ($table) {
        $this->escape (func_get_args ());
        if (is_string ($table)) {
            return $result = $this->query ("SHOW COLUMNS FROM $table", $this->link);
        } else {
            $result = $table;
            if ($result) {
                for ($i = 0; $i < mysql_num_fields ($result); $i++) {
                    $fields[$i] = mysql_fetch_field ($result, $i);
                }
                return $fields;
            } else {
                return false;
            }
        }
    }

    public function getLink () {
        return $this->link;
    }

    public function getTables () {
        $result = $this->query ("SHOW TABLES FROM " . DATABASE);
        $tables = array ();
        for ($i = 0; $row = mysql_fetch_assoc ($result); $i++) {
            $tables[$i] = mysql_tablename ($result, $i);
        }
        return $tables;
    }

    /**
     * This method creates and submits a query to database
     *
     * @param string $table the name of the the table
     * @param array $values an associative array containing the fields as indexes of the values that will be used
     * @return resource returns a resource if successfull else false
     */
    public function insert ($table, $values, $ignore = false) {
        $this->escape (func_get_args ());
        $query = 'INSERT ';
        if ($ignore) {
            $query .= 'IGNORE ';
        }
        $query .= " INTO $table (";
        $tmp = ") VALUES (";
        foreach ($values as $key => $value) {
            if (!$this->allow_empty_values && empty ($value)) {
                return false;
            }
            $query .= "$key, ";
            $value = strval ($value);
            if (!empty ($value)) {
                if ($value[strlen ($value) - 1] == ')') {
                    $tmp .= "$value, ";
                } else {
                    $tmp .= "'$value', ";
                }
            } else {
                $tmp .= "'', ";
            }
        }
        $query = substr ($query, 0, strlen ($query) - 2);
        $tmp = substr ($tmp, 0, strlen ($tmp) - 2);
        $tmp .= ")";
        $query .= $tmp;
        return $this->query ($query);
    }

    /**
     * This method submits the specified query to database
     *
     * @param string $query the query that will be submitted
     * @param resource $link [Optional] the link identifier of the connection to use
     * @return resource returns a resource if successfull else false
     */
    public function query ($query, $link = null) {
        $this->escape (func_get_args ());
        if ($this->debug_mode) {
            echo $query . '<br>';
        }
        if (isset ($link)) {
            $this->link = $link;
            $result = mysql_query ($query, $link);
        } else {
            $result = mysql_query ($query);
        }
        return $result;
    }

    public function realEscapeString ($str) {
        return mysql_real_escape_string ($str, $this->link);
    }

    public function select ($tables, $fields = null, $where = null, $group_by = null, $order_by = null, $limit = null) {
        $this->escape (func_get_args ());
        $query = "SELECT ";
        if (isset ($fields) && !empty ($fields)) {
            if (is_array ($fields)) {
                foreach ($fields as $field) {
                    $query .= "$field, ";
                }
                $query = substr ($query, 0, strlen ($query) - 2);
            } else if (is_string ($fields)) {
                if ($fields) {
                    $query .= "$fields";
                }
            }
        } else {
            $query .= "*";
        }
        $query .= " FROM ";
        if (is_array ($tables)) {
            foreach ($tables as $value) {
                $query .= "$value, ";
            }
            $query = substr ($query, 0, strlen ($query) - 2);
        } else if (is_string ($tables)) {
            $query .= "$tables";
        }
        if (isset ($where) && !empty ($where)) {
            $query .= " WHERE $where";
        }
        if (isset ($group_by) && !empty ($group_by)) {
            $query .= " GROUP BY $group_by";
        }
        if (isset ($order_by) && !empty ($order_by)) {
            $query .= " ORDER BY $order_by";
        }
        if (isset ($limit) && !empty ($limit)) {
            $query .= " LIMIT";
            if (is_numeric ($limit)) {
                $query .= " $limit";
            } else if (is_array ($limit) && count ($limit) == 2) {
                $query .= " $limit[0], $limit[1]";
            }
        }
        return $this->query ($query);
    }

    /**
     * This method allows to choose the database to use
     * @param string $database the name of the database
     * @return true on success or false on failure
     */
    public function selectDatabase ($database) {
        $this->escape (func_get_args ());
        $this->database = $database;
        return mysql_select_db ($database);
    }

    /**
     *
     * If debug mode is activated every time <code>query</code> method is called the query will be printed
     *
     * @param bool $var if true debug mode will be activated
     * @return bool true if and only if <var>$var</var> value is bool and debug mode is activated/deactivated, else false
     */
    public function setDebugMode ($var) {
        if (is_bool ($var)) {
            $this->debug_mode = $var;
            return true;
        }
        return false;
    }

    public function sum ($table, $field = '*', $where = '1') {
        $row = $this->fetchAssoc ($this->select ($table, "SUM($field) AS n", $where));
        return $row['n'];
    }

    public function update ($tables, $values, $where = null) {
        $this->escape (func_get_args ());
        if (is_array ($tables)) {
            $str = '';
            foreach ($tables as $table) {
                $str .= "$table,";
            }
            $tables = substr ($str, 0, strlen ($str) - 1);
        }
        $query = "UPDATE $tables SET ";
        foreach ($values as $key => $value) {
            if (isset ($value[strlen ($value) - 1]) && $value[strlen ($value) - 1] == ')') {
                $query .= "$key=$value, ";
            } else {
                $query .= "$key='$value', ";
            }
        }
        $query = substr ($query, 0, strlen ($query) - 2);
        if (isset ($where) && !empty ($where)) {
            $query .= " WHERE $where";
        }
        return $this->query ($query);
    }

    /**
     * This method escapes all dangerous characters that could cause problems
     * 
     * @param array $array containing all the strings to escape
     */
    private function escape ($array) {
        if ($this->escape) {
            for ($i = 0; $i < count ($array); $i++) {
                if (is_string ($array[$i])) {
                    $array[$i] = addslashes ($array[$i]);
                }
            }
        }
    }

}

?>
